package com.chuangke.common.trans.aspect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.chuangke.common.data.builder.DataBuildConfig;
import com.chuangke.common.data.builder.DataBuilder;
import com.chuangke.common.data.builder.IDataBuilder;
import com.chuangke.common.trans.annotation.Trans;
import com.chuangke.common.utils.ReflectionUtils;

import cn.hutool.core.util.StrUtil;

/**
 * 结果翻译aop
 */
@Aspect
@Component
public class TransResultAop {

	private static final Logger logger = LoggerFactory.getLogger(TransResultAop.class);

	@Around("@annotation(com.chuangke.common.trans.annotation.TransResult)")
	public Object transResult(ProceedingJoinPoint joinPoint) throws Throwable {
		Object proceed = joinPoint.proceed();

		long start = System.currentTimeMillis();
		transObject(proceed);
		long end = System.currentTimeMillis();
		logger.warn("数据翻译时间：" + (end - start) + "ms");

		return proceed;
	}

	private boolean isCanTrans(Object object) {
		if(object.getClass().isPrimitive()) {
			return false ;
		}
		
		if(object instanceof Collection) {
			return true ;
		}
		
		String packageName = object.getClass().getPackage().getName() ;
        return !packageName.startsWith("java") && !packageName.startsWith("sun");
    }
	
	private void transObject(Object object) {
		if (object == null) {
			return;
		}

		if(!isCanTrans(object)) {
			return;
		}

        /* 翻译是对集合进行翻译；如果是非集合单个值，需要将值包装成集合 */
		Collection<?> collection = object instanceof Collection ? (Collection<?>) object : Arrays.asList(object);

		if (CollectionUtils.isEmpty(collection)) {
			return;
		}

        /* 获取数据的字段信息 */
		Object firstObject = collection.iterator().next();
		List<Field> fields = ReflectionUtils.getAllField(firstObject);

		if (CollectionUtils.isEmpty(fields)) {
			return;
		}

		List<Trans> tranList = new ArrayList<>();
		for (Field field : fields) {
			int mod = field.getModifiers();
			// 如果是 static, final, volatile, transient 的字段，则直接跳过
			if (Modifier.isStatic(mod) || Modifier.isFinal(mod) || Modifier.isVolatile(mod)) {
				continue;
			}

			Trans trans = field.getAnnotation(Trans.class);
			if (trans == null) {
                /* 深度翻译 */
				Object feildObj = null;
				try {
					field.setAccessible(true);
					feildObj = field.get(firstObject);
				} catch (Exception e) {
					e.printStackTrace();
				}
				transObject(feildObj);

				continue;
			}

			tranList.add(trans);
		}

		if (CollectionUtils.isEmpty(tranList)) {
			return;
		}

        /* 进行翻译 */
		Map<String, List<Trans>> tranMap = tranList.stream()
				.collect(Collectors.groupingBy(a -> a.dataBuilder().getName() + "#" + a.dictType()));

		DataBuilder dataBuilder = DataBuilder.of(collection);

		for (List<Trans> transGroup : tranMap.values()) {
			Trans firstTrans = transGroup.get(0);

			IDataBuilder<?> idb = StrUtil.isBlank(firstTrans.dictType())
					? ReflectionUtils.getInstance(firstTrans.dataBuilder(), firstTrans.dataType())
					: ReflectionUtils.getInstance(firstTrans.dataBuilder(), firstTrans.dictType(), firstTrans.dataType());
			
			DataBuildConfig[] dbcs = new DataBuildConfig[transGroup.size()];

			for (int i = 0; i < transGroup.size(); i++) {
				dbcs[i] = new DataBuildConfig(transGroup.get(i).key(), transGroup.get(i).ref());
				dbcs[i].setMultiple(transGroup.get(i).isMultipleKey());
				dbcs[i].setSeparator(transGroup.get(i).keySeparator());
			}

			dataBuilder.appendBuilder(idb, dbcs);
		}

		dataBuilder.build();
	}

}
